

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column, Integer, String, Binary, ForeignKey, Boolean,\
                       Float, PickleType
from sqlalchemy.orm import relation
from sqlalchemy.schema import UniqueConstraint, Table

#===============================================================================
# GLOBALS
#===============================================================================
MAX_INDIVIDUALS = 1000
Base = declarative_base()

#===============================================================================
# TABLE DEFINITIONS
#===============================================================================
class Schema(Base):
    __table__ = Table('schema', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, unique=True, nullable=False),
                      Column('zip_data', Binary, nullable=False),
                      Column('last_modified_time', Float, nullable=False)
                )
    populations = relation("Population", backref="schema")
    
    def __init__(self, name, zip_data, last_modified_time):
        self.name = name
        self.zip_data = zip_data
        self.last_modified_time = last_modified_time
    
    def __repr__(self):
        return "<Schema('%s', '%s')>" % (self.name, self.last_modified_time)


class Population(Base):   
    __table__ = Table('population', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, nullable=False),
                      Column('max_inds', Integer),
                      Column('model_name', String),
                      Column('image_name', String),
                      Column('is_stopped', Boolean, nullable=False),
                      Column('global_data', PickleType),
                      Column('schema_id', Integer, ForeignKey('schema.id'), 
                             nullable=False),
                      Column('creation_time', Float, nullable=False),
                      UniqueConstraint('name', 'schema_id')
                )
    tasks = relation("Task", order_by="Task.id", backref="population")
    
    def __init__(self, name):
        self.name = name
        self.is_stopped = False
        self.max_inds = MAX_INDIVIDUALS
        
    def __repr__(self):
        return "<Population('%s', '%s', '%s', '%s')>"\
               %(self.name, self.max_inds, self.model_name, self.image_name)


class Task(Base):    
    __table__ = Table('task', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, nullable=False),
                      Column('file_name', String, nullable=False),
                      Column('class_name', String, nullable=False),
                      Column('input_size', Integer),
                      Column('population_id', Integer, 
                             ForeignKey('population.id'), nullable=False),
                      Column('is_stopped', Boolean, nullable=False)
                )
    
    def __init__(self, name, file_name, class_name, input_size=None):
        self.name = name
        self.file_name = file_name
        self.class_name = class_name
        self.input_size = input_size
        self.is_stopped = False
   
    def get_dict(self):
        res = {}
        res["name"] = self.name
        res["class_name"] = self.class_name
        res["file_name"] = self.file_name
        res["input_size"] = self.input_size
        return res
         
    def __repr__(self):
        return "<Task('%s', '%s', '%s', '%s', '%s')>"\
               %(self.name, self.file_name, self.class_name, self.input_size,
                 self.is_stopped)
